# 5. 运算符

# 运算符的基本介绍

运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等

  1. 算术运算符

    运算符 描述
    + 相加
    - 相减
    * 相乘
    / 相除
    % 求余

    注意: ++(自增)和--(自减)在Go语言中是单独的语句,并不是运算符。

  2. 逻辑运算符

    运算符 描述
    && 逻辑 AND 运算符。 如果两边的操作数都是 True,则为 True,否则为 False。
    || 逻辑 OR 运算符。 如果两边的操作数有一个 True,则为 True,否则为 False。
    ! 逻辑 NOT 运算符。 如果条件为 True,则为 False,否则为 True。
  3. 比较运算符/关系运算符

    运算符 描述
    == 检查两个值是否相等,如果相等返回 True 否则返回 False。
    != 检查两个值是否不相等,如果不相等返回 True 否则返回 False。
    > 检查左边值是否大于右边值,如果是返回 True 否则返回 False。
    >= 检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。
    < 检查左边值是否小于右边值,如果是返回 True 否则返回 False。
    <= 检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。
  4. 赋值运算符

    运算符 描述
    = 简单的赋值运算符,将一个表达式的值赋给一个左值
    += 相加后再赋值
    -= 相减后再赋值
    *= 相乘后再赋值
    /= 相除后再赋值
    %= 求余后再赋值
    <<= 左移后赋值
    >>= 右移后赋值
    &= 按位与后赋值
    |= 按位或后赋值
    ^= 按位异或后赋值
  5. 位运算符:位运算符对整数在内存中的二进制位进行操作。

    运算符 描述
    & 参与运算的两数各对应的二进位相与。 (两位均为1才为1)
    | 参与运算的两数各对应的二进位相或。 (两位有一个为1就为1)
    ^ 参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。 (两位不一样则为1)
    << 左移n位就是乘以2的n次方。 “a<<b”是把a的各二进位全部左移b位,高位丢弃,低位补0。
    >> 右移n位就是除以2的n次方。 “a>>b”是把a的各二进位全部右移b位。
  6. 其它运算符

# 运算符的优先级

image-20200813201247082

  1. 运算符有不同的优先级,所谓优先级就是表达式运算中的运算顺序。如右表,上一行运算符总优先于下一行
  2. 只有单目运算符、赋值运算符是从右向左运算的。
  3. 梳理了一个大概的优先级
    1. 括号,++, --
    2. 单目运算
    3. 算术运算符
    4. 移位运算
    5. 关系运算符
    6. 位运算符
    7. 逻辑运算符
    8. 赋值运算符
    9. 逗号

# 三元运算特别说明

image-20200813115954786

如果在 golang 中实现三元运算的效果。

image-20200813201217240

# 算术运算符

算术运算符是对数值类型的变量进行运算的,比如:加减乘除。在 Go 程序中使用的非常多

image-20200813103802364

# 演示

+, - , * , / , %, ++, -- , 重点讲解 /、%、自增:++、自减:--

  1. 演示 / 的使用的特点

    image-20200813103916979

  2. 演示 % 的使用特点

    // 演示 % 的使用
    // 看一个公式 a % b = a - a / b * b
    fmt.Println("10%3=", 10 % 3) // =1
    fmt.Println("-10%3=", -10 % 3) // = -10 - (-10) / 3 * 3 = -10 - (-9) = -1
    fmt.Println("10%-3=", 10 % -3) // =1
    fmt.Println("-10%-3=", -10 % -3) // =-1
    
  3. ++ 和 --的使用

    image-20200813103949417

# 算术运算符使用的注意事项

  1. 对于除号 "/",它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。 例如: x := 19/5 ,结果是 3

  2. 当对一个数取模时,可以等价 a%b=a-a/b*b , 这样我们可以看到 取模的一个本质运算

  3. Golang 的自增自减只能当做一个独立语言使用时,不能这样使用

image-20200813104040852

  1. Golang 的++ 和 -- 只能写在变量的后面,不能写在变量的前面,即:只有 a++ a-- 没有 ++a --a

    image-20200813104058560

  2. Golang 的设计者去掉 c / java 中的 自增自减的容易混淆的写法,让 Golang 更加简洁,统一。(强制性的)

# 练习1

image-20200813104201482

# 练习2

  1. 假如还有 97 天放假,问:xx 个星期零 xx 天
  2. 定义一个变量保存华氏温度,华氏温度转换摄氏温度的公式为:5/9*(华氏温度-100),请求出华氏温度对应的摄氏温度。

image-20200813105020994

# 关系运算符(比较运算符)

  1. 关系运算符的结果都是 bool 型,也就是要么是 true,要么是 false
  2. 关系表达式 经常用在 if 结构的条件中或 循环结构的条件中
运算符 描述
== 检查两个值是否相等,如果相等返回 True 否则返回 False。
!= 检查两个值是否不相等,如果不相等返回 True 否则返回 False。
> 检查左边值是否大于右边值,如果是返回 True 否则返回 False。
>= 检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。
< 检查左边值是否小于右边值,如果是返回 True 否则返回 False。
<= 检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。

# 演示

image-20200813115106742

# 关系运算符的细节说明

  1. 关系运算符的结果都是 bool 型,也就是要么是 true,要么是 false。
  2. 关系运算符组成的表达式,我们称为关系表达式: a > b
  3. 比较运算符"=="不能误写成 "=" !!

# 逻辑运算符

用于连接多个条件(一般来讲就是关系表达式),最终的结果也是一个 bool 值

运算符 描述
&& 逻辑 AND 运算符。 如果两边的操作数都是 True,则为 True,否则为 False。
|| 逻辑 OR 运算符。 如果两边的操作数有一个 True,则为 True,否则为 False。
! 逻辑 NOT 运算符。 如果条件为 True,则为 False,否则为 True。

# 演示

image-20200813115249791

image-20200813115256518

# 逻辑运算符的细节说明

  1. &&也叫 短路与: 如果第一个条件为 false,则 第二个条件不会判断,最终结果为 false
  2. ||也叫 短路或:如果 第一个条件为 true,则 第二个条件不会判断,最终结果为 true

image-20200813115347568

# 赋值运算符

赋值运算符就是将某个运算后的值,赋给指定的变量

运算符 描述
= 简单的赋值运算符,将一个表达式的值赋给一个左值
+= 相加后再赋值
-= 相减后再赋值
*= 相乘后再赋值
/= 相除后再赋值
%= 求余后再赋值
<<= 左移后赋值
>>= 右移后赋值
&= 按位与后赋值
|= 按位或后赋值
^= 按位异或后赋值

# 演示

  1. 有两个变量,a 和 b,要求将其进行交换,最终打印结果
  2. += 的使用案例

image-20200813115519342

# 赋值运算符的细节说明

  1. 运算顺序从右往左

image-20200813115548650

  1. 赋值运算符的左边 只能是 变量,右边 可以是 变量、表达式、常量值

    image-20200813115601165

  2. 复合赋值运算符等价于下面的效果

    1. 比如:a += 3 等价于 a = a + 3

# 练习

有两个变量,a 和 b,要求将其进行交换,但是不允许使用中间变量,最终打印结果image-20200813115715372

# 其它运算符

image-20200813115811172

# 演示

image-20200813115833724

# 练习

  1. 求两个数的最大值

    image-20200813115913460

  2. 求三个数的最大值

    image-20200813115926181

# 进制

为什么这里要有进制,因为接下来的运算符需要进制

对于整数,有四种表示方式

  1. 二进制:0,1 ,满 2 进 1
    1. 在 golang 中,不能直接使用二进制来表示一个整数,它沿用了 c 的特点
  2. 十进制:0-9 ,满 10 进 1
  3. 八进制:0-7 ,满 8 进 1. 以数字 0 开头表示。
  4. 十六进制:0-9 及 A-F,满 16 进 1. 以 0x 或 0X 开头表示。
    1. 此处的 A-F 不区分大小写

image-20200813201919538

# 进制的图示

image-20200813201940752

image-20200813201943777

# 进制转换的介绍

image-20200813201956080

# 其它进制转十进制

image-20200813202006449

# 二进制如何转十进制

image-20200813202022990

# 八进制转换成十进制示例

image-20200813202050415

# 16 进制转成 10 进制

image-20200813202101191

# 十进制如何转成其它进制

image-20200813202342648

# 十进制如何转二进制

image-20200813202356322

# 十进制转成八进制

image-20200813202406662

# 十进制转十六进制

image-20200813202416751

# 二进制转换成八进制、十六进制

image-20200813202428637

# 二进制转换成八进制

image-20200813202439493

# 二进制转成十六进制

image-20200813202452702

# 八进制、十六进制转成二进制

image-20200814175646175

# 八进制转换成二进制

image-20200814175703998

# 十六进制转成二进制

image-20200814175715582

# 位运算

位运算符对整数在内存中的二进制位进行操作。

运算符 描述
& 参与运算的两数各对应的二进位相与。 (两位均为1才为1)
| 参与运算的两数各对应的二进位相或。 (两位有一个为1就为1)
^ 参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。 (两位不一样则为1)
<< 左移n位就是乘以2的n次方。 “a<<b”是把a的各二进位全部左移b位,高位丢弃,低位补0。
>> 右移n位就是除以2的n次方。 “a>>b”是把a的各二进位全部右移b位。

# 位运算的思考题

//请看下面的代码段,回答 a,b,c,d 结果是多少?
func main() {
    var a int = 1 >> 2
    var b int = -1 >> 2
    var c int = 1 << 2
    var d int = -1 << 2
    //a,b,c,d 结果是多少
    fmt.Println("a=", a)
    fmt.Println("b=", b)
    fmt.Println("c=", c)
    fmt.Println("d=", d)
}


// 请回答在 Golang 中,下面的表达式运算的结果是:
func main() {
    fmt.Println(2&3)
    fmt.Println(2|3)
    fmt.Println(13&7)
    fmt.Println(5|4) //?
    fmt.Println(-3^3) //?
}

# 二进制在运算中的说明

  1. 二进制是逢 2 进位的进位制,0、1 是基本算符。
  2. 现代的电子计算机技术全部采用的是二进制,因为它只使用 0、1 两个数字符号,非常简单方便易于用电子方式实现。
  3. 计算机内部处理的信息,都是采用二进制数来表示的。二进制(Binary)数用 0 和 1 两个数字及其组合来表示任何数。
  4. 进位规则是“逢 2 进 1”,数字 1 在不同的位上代表不同的值,按从右至左的次序,这个值以二倍递增

在计算机的内部,运行各种运算时,都是以二进制的方式来运行

# 原码、反码、补码

image-20200814180002461

# 位运算符和移位运算符

# Golang 中有 3 个位运算

  1. 分别是”按位与&、按位或|、按位异或^,它们的运算规则是:
  2. 按位与 & : 两位全为1,结果为 1 ,否则为 0
  3. 按位或 | : 两位有一个为 1 ,结果为 1 ,否则为 0
  4. 或 按位异或 ^ : 两位一个为 0, 一个为 1 ,结果为 1 ,否则为 0

# 演示

题目:2&3=? 2|3=? 2^3=?

image-20200814180118335

image-20200814180125883

# Golang 中有 2 个移位运算符

>>、<< 右移和左移,运算规则:

  1. 右移运算符 >>: 低位溢出, 符号位不变, 并用符号位补溢出的高位
  2. 左移运算符 <<: 符号位不变,
a := 1 >> 2 // 0000 0001 =>0000 0000 = 0
c := 1 << 2 // 0000 0001 ==> 0000 0100 => 4